import json
import random
import time

from django import http
from django.db import transaction
from django_redis import get_redis_connection
from django.shortcuts import render
from django.views.generic import View

from goods.models import SKU
from meiduo_mall.utils.constants import Code
from meiduo_mall.utils.login_required import MyLoginRequest
from users.models import Address
from .models import OrderGoods, OrderInfo
from django.utils import timezone
from django.core.paginator import Paginator


class OrderSettlementView(MyLoginRequest):

    def get(self, request):
        user = request.user
        # 获取地址信息
        address_list = []
        for address in user.addresses.all():
            if address.is_deleted:
                continue
            address_list.append({
                'id': address.id,
                'province': address.province.name,
                'city': address.city.name,
                'district': address.district.name,
                'place': address.place,
                'mobile': address.mobile,
                'receiver': address.receiver
            })

        # 结算商品信息
        redis_conn = get_redis_connection('carts')
        skus = []
        selected_goods = redis_conn.smembers('selected_%d' % user.id)
        cart_dic = redis_conn.hgetall('cart_%d' % user.id)

        total_amount = 0
        total_count = 0

        for sku_id in selected_goods:
            sku = SKU.objects.get(id=sku_id)
            skus.append({
                'img': sku.default_image_url.url,
                'name': sku.name,
                'price': str(sku.price),
                'count': int(cart_dic.get(sku_id)),
                'amount': str(sku.price * int(cart_dic[sku_id]))

            })
            total_amount += sku.price * int(cart_dic[sku_id])
            total_count += int(cart_dic[sku_id])

        context = {
            "address_list": address_list,
            'default_address_id': user.default_address_id,
            'skus': skus,
            'total_amount': total_amount,
            'total_count': total_count,
            'transit': 10
        }
        return render(request, 'place_order.html', context=context)


class OrderCommitView(MyLoginRequest):

    def post(self, request):
        data_dict = json.loads(request.body.decode())
        address_id = data_dict.get('address_id')
        pay_method = int(data_dict.get('pay_method'))

        # 参数校验
        if not all([address_id, pay_method]):
            return http.JsonResponse({'code': Code.PARAMETER_ERROR, 'errmsg': '参数不全'})

        try:
            address = Address.objects.get(id=address_id)
        except:
            return http.JsonResponse({'code': Code.PARAMETER_ERROR, 'errmsg': '地址不存在'})

        if pay_method not in OrderInfo.PAY_METHODS_ENUM.values():
            return http.JsonResponse({'code': Code.PARAMETER_ERROR, 'errmsg': '支付方式不正确'})

        user = request.user
        order_id = timezone.localtime().strftime('%Y%m%d%H%m%s') + '%06d%d' % (random.randint(0, 999999), user.id)

        # 连接redis取出购物车数据
        redis_conn = get_redis_connection('carts')
        selected_goods = redis_conn.smembers('selected_%d' % user.id)
        cart_dict = redis_conn.hgetall('cart_%d' % user.id)
        if not cart_dict:
            return http.JsonResponse({'code': Code.PARAMETER_ERROR, 'errmsg': '订单商品不能为空'})

        with transaction.atomic():
            save_id = transaction.savepoint()
            order_info = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=0,
                total_amount=0,
                freight=10,
                pay_method=pay_method
            )

            total_count = 0
            total_amount = 0
            for sku_id in selected_goods:
                while True:
                    sku = SKU.objects.get(id=sku_id)
                    count = int(cart_dict[sku_id])
                    if count > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return http.JsonResponse({'code': Code.PARAMETER_ERROR, 'errmsg': '商品：%s 库存不足' % sku.name})

                    old_stock = sku.stock
                    old_sales = sku.sales
                    new_stock = old_stock - count
                    new_sales = old_sales + count

                    sss = SKU.objects.filter(id=sku_id, stock=old_stock).first()
                    c = sss.stock

                    row = SKU.objects.filter(id=sku_id, stock=old_stock).update(stock=new_stock, sales=new_sales)
                    if row == 0:
                        continue

                    # 创建订单商品对象
                    order_good = OrderGoods.objects.create(
                        order=order_info,
                        sku=sku,
                        count=count,
                        price=sku.price,
                    )
                    total_count += count
                    total_amount += count * sku.price
                    break

            order_info.total_amount = total_amount
            order_info.total_count = total_count
            order_info.save()

            transaction.savepoint_commit(save_id)

        redis_conn.hdel('cart_%d' % user.id, *selected_goods)
        redis_conn.srem('selected_%d' % user.id, *selected_goods)

        return http.JsonResponse({'code': Code.OK, 'order_id': order_info.order_id})




class OrderSuccessView(MyLoginRequest):
    def get(self, request):
        data_dict = request.GET
        order_id = data_dict.get('order_id')
        payment_amount = data_dict.get('payment_amount')
        pay_method = data_dict.get('pay_method')
        context = {
            'payment_amount': payment_amount,
            'order_id': order_id,
            'pay_method': pay_method
        }
        return render(request, 'order_success.html', context=context)


class UserCenterOrderView(MyLoginRequest):
    def get(self, request, page_id):
        orders = request.user.orderinfo_set.order_by('-create_time').all()

        paginator = Paginator(orders, 2)
        page = paginator.page(page_id)
        current_page = page.number
        total_page = paginator.num_pages
        order_list = []
        for order in page.object_list:
            order_list.append(
                {
                    'order_id': str(order.order_id),
                    'create_time': order.create_time,
                    'skus': order.skus.all(),
                    'total_amount': order.total_amount,
                    'freight': order.freight,
                    'paymethod': OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1],
                    'status_str': OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1],
                    'status': order.status
                }
            )

        context = {
            'order_list': order_list,
            'current_page': current_page,
            'total_page': total_page
        }

        return render(request, 'user_center_order.html', context=context)
